home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library / Microsoft Programmer's Library (CD-ROM Database)(125-099-008)(Version 1.1a)(CDRM 162100)(1989).iso / SAMPCODE / OS2SDK11 / TK4 / PMCAP / PMCAP2.C < prev    next >
C/C++ Source or Header  |  1989-02-20  |  18KB  |  559 lines

  1. /*----------------------------------
  2.    PMCAP2.C -- Routines for PMCAP.C
  3.   ----------------------------------*/
  4.  
  5. #define INCL_WIN
  6. #define INCL_GPI
  7. #define INCL_BITMAPFILEFORMAT
  8. #include <os2.h>
  9. #include <ctype.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "pmcap.h"
  14.  
  15. extern CHAR szClientClass [] ;
  16. extern HAB  hab ;
  17.  
  18. VOID CheckMenuItem (HWND hwndMenu, SHORT idItem, BOOL fCheck)
  19.      {
  20.      WinSendMsg (hwndMenu, MM_SETITEMATTR,
  21.                  MPFROM2SHORT (idItem, TRUE),
  22.                  MPFROM2SHORT (MIA_CHECKED, fCheck ? MIA_CHECKED : 0)) ;
  23.      }
  24.  
  25. VOID EnableMenuItem (HWND hwndMenu, SHORT idItem, BOOL fEnable)
  26.      {
  27.      WinSendMsg (hwndMenu, MM_SETITEMATTR,
  28.                  MPFROM2SHORT (idItem, TRUE),
  29.                  MPFROM2SHORT (MIA_DISABLED, fEnable ? 0 : MIA_DISABLED)) ;
  30.      }
  31.  
  32. VOID ErrorMessage (HWND hwnd, SHORT idError)
  33.      {
  34.      CHAR achString [80] ;
  35.  
  36.      WinLoadString (hab, NULL, idError, sizeof achString, achString) ;
  37.  
  38.      WinMessageBox (HWND_DESKTOP, hwnd, achString, szClientClass, 0,
  39.                     MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE) ;
  40.      }
  41.  
  42. VOID AddItemToSysMenu (HWND hwndFrame)
  43.      {
  44.      static CHAR     *szMenuText [2] = { NULL, "~Begin countdown" } ;
  45.      static MENUITEM mi [2] = {
  46.                               MIT_END, MIS_SEPARATOR, 0,         0, NULL, NULL,
  47.                               MIT_END, MIS_TEXT,      0, IDM_BEGIN, NULL, NULL
  48.                               } ;
  49.      HWND            hwndSysMenu, hwndSysSubMenu ;
  50.      MENUITEM        miSysMenu ;
  51.      SHORT           idSysMenu, sItem ;
  52.  
  53.      hwndSysMenu = WinWindowFromID (hwndFrame, FID_SYSMENU) ;
  54.      idSysMenu   = SHORT1FROMMR (WinSendMsg (hwndSysMenu,
  55.                                              MM_ITEMIDFROMPOSITION,
  56.                                              NULL, NULL)) ;
  57.  
  58.      WinSendMsg (hwndSysMenu, MM_QUERYITEM,
  59.                  MPFROM2SHORT (idSysMenu, FALSE),
  60.                  MPFROMP (&miSysMenu)) ;
  61.  
  62.      hwndSysSubMenu = miSysMenu.hwndSubMenu ;
  63.  
  64.      for (sItem = 0 ; sItem < 2 ; sItem++)
  65.           WinSendMsg (hwndSysSubMenu, MM_INSERTITEM,
  66.                       MPFROMP (mi + sItem),
  67.                       MPFROMP (szMenuText [sItem])) ;
  68.      return ;
  69.      }
  70.  
  71. VOID SaveColorSettings (BOOL fSave, BOOL fSetMono)
  72.      {
  73.      static LONG clrTableDef [2 * SYSCLR_CSYSCOLORS] ;
  74.      static LONG clrTable [] = { SYSCLR_WINDOWSTATICTEXT, 0x000000,
  75.                                  SYSCLR_SCROLLBAR,        0xC0C0C0,
  76.                                  SYSCLR_BACKGROUND,       0xFFFFFF,
  77.                                  SYSCLR_ACTIVETITLE,      0x000000,
  78.                                  SYSCLR_INACTIVETITLE,    0xFFFFFF,
  79.                                  SYSCLR_MENU,             0xFFFFFF,
  80.                                  SYSCLR_WINDOW,           0xFFFFFF,
  81.                                  SYSCLR_WINDOWFRAME,      0x000000,
  82.                                  SYSCLR_MENUTEXT,         0x000000,
  83.                                  SYSCLR_WINDOWTEXT,       0x000000,
  84.                                  SYSCLR_TITLETEXT,        0xFFFFFF,
  85.                                  SYSCLR_ACTIVEBORDER,     0xA0A0A0,
  86.                                  SYSCLR_INACTIVEBORDER,   0xFFFFFF,
  87.                                  SYSCLR_APPWORKSPACE,     0xE0E0E0,
  88.                                  SYSCLR_HELPBACKGROUND,   0xFFFFFF,
  89.                                  SYSCLR_HELPTEXT,         0x000000,
  90.                                  SYSCLR_HELPHILITE,       0x000000 } ;
  91.      SHORT i ;
  92.  
  93.      if (fSave)
  94.           for (i = 0 ; i < SYSCLR_CSYSCOLORS ; i++)
  95.                clrTableDef[2*i+1] = WinQuerySysColor (HWND_DESKTOP,
  96.                                         clrTableDef[2*i] = clrTable[2*i], 0L);
  97.  
  98.      if (fSetMono)
  99.           WinSetSysColors (HWND_DESKTOP, 0L, LCOLF_INDRGB,
  100.                            0L, 2 * SYSCLR_CSYSCOLORS, clrTable) ;
  101.      else
  102.           WinSetSysColors (HWND_DESKTOP, 0L, LCOLF_INDRGB,
  103.                            0L, 2 * SYSCLR_CSYSCOLORS, clrTableDef) ;
  104.      return ;
  105.      }
  106.  
  107. VOID IncrementFilename (CHAR *pchName)
  108.      {
  109.      SHORT sIndex ;
  110.  
  111.      for (sIndex = strlen (pchName) - 1 ; sIndex >= 0 ; sIndex--)
  112.           {
  113.           if (pchName [sIndex] == '\\')      // past filename
  114.                return ;
  115.  
  116.           if (isdigit (pchName [sIndex]))
  117.                break ;
  118.           }
  119.  
  120.      for ( ; sIndex >= 0 ; sIndex--)
  121.           {
  122.           if (!isdigit (pchName [sIndex]))
  123.                return ;
  124.  
  125.           if (pchName [sIndex] == '9')
  126.                pchName [sIndex] = '0' ;
  127.           else
  128.                {
  129.                pchName [sIndex] += '\001' ;
  130.                return ;
  131.                }
  132.           }
  133.      return ;
  134.      }
  135.  
  136. HBITMAP CopyBitmap (HBITMAP hbmSrc)
  137.      {
  138.      BITMAPINFOHEADER bmp ;
  139.      HBITMAP          hbmDst ;
  140.      HDC              hdcSrc, hdcDst ;
  141.      HPS              hpsSrc, hpsDst ;
  142.      POINTL           aptl[3] ;
  143.      SIZEL            sizl ;
  144.  
  145.      hdcSrc = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  146.      hdcDst = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  147.  
  148.      sizl.cx = sizl.cy = 0 ;
  149.      hpsSrc = GpiCreatePS (hab, hdcSrc, &sizl, PU_PELS    | GPIF_DEFAULT |
  150.                                                GPIT_MICRO | GPIA_ASSOC) ;
  151.  
  152.      hpsDst = GpiCreatePS (hab, hdcDst, &sizl, PU_PELS    | GPIF_DEFAULT |
  153.                                                GPIT_MICRO | GPIA_ASSOC) ;
  154.  
  155.      GpiQueryBitmapParameters (hbmSrc, &bmp) ;
  156.      hbmDst = GpiCreateBitmap (hpsDst, &bmp, 0L, NULL, NULL) ;
  157.  
  158.      if (hbmDst != NULL)
  159.           {
  160.           GpiSetBitmap (hpsSrc, hbmSrc) ;
  161.           GpiSetBitmap (hpsDst, hbmDst) ;
  162.  
  163.           aptl[0].x = aptl[0].y = 0 ;
  164.           aptl[1].x = bmp.cx ;
  165.           aptl[1].y = bmp.cy ;
  166.           aptl[2]   = aptl[0] ;
  167.  
  168.           GpiBitBlt (hpsDst, hpsSrc, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  169.           }
  170.      GpiDestroyPS (hpsSrc) ;
  171.      GpiDestroyPS (hpsDst) ;
  172.      DevCloseDC (hdcSrc) ;
  173.      DevCloseDC (hdcDst) ;
  174.  
  175.      return hbmDst ;
  176.      }
  177.  
  178. VOID CopyPointerToScreen (HPS hpsScreen, LONG alBitmapFormats[], BOOL fCopy)
  179.      {
  180.      static HBITMAP     hbm ;
  181.      static HDC         hdcMemory ;
  182.      static HPS         hpsMemory ;
  183.      static POINTERINFO ptri ;
  184.      static POINTL      ptlPointer, aptl[3] ;
  185.      static SHORT       cxPointer, cyPointer ;
  186.      BITMAPINFOHEADER   bmp ;
  187.      HPOINTER           hptr ;
  188.      SIZEL              sizl ;
  189.  
  190.      if (WinQuerySysValue (HWND_DESKTOP, SV_MOUSEPRESENT) == 0L)
  191.           return ;
  192.  
  193.      if (fCopy)
  194.           {
  195.                                    // Get Pointer Information
  196.  
  197.           cxPointer = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CXPOINTER) ;
  198.           cyPointer = (SHORT) WinQuerySysValue (HWND_DESKTOP, SV_CYPOINTER) ;
  199.  
  200.           hptr = WinQueryPointer (HWND_DESKTOP) ;
  201.           WinQueryPointerInfo (hptr, &ptri) ;
  202.           WinQueryPointerPos (HWND_DESKTOP, &ptlPointer) ;
  203.  
  204.                                    // Create memory DC and PS
  205.  
  206.           hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  207.  
  208.           sizl.cx = sizl.cy = 0 ;
  209.           hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
  210.                                    PU_PELS    | GPIF_DEFAULT |
  211.                                    GPIT_MICRO | GPIA_ASSOC) ;
  212.  
  213.                                    // Create bitmap for destination
  214.  
  215.           bmp.cbFix     = sizeof bmp ;
  216.           bmp.cx        = cxPointer ;
  217.           bmp.cy        = cyPointer ;
  218.           bmp.cPlanes   = (USHORT) alBitmapFormats[0] ;
  219.           bmp.cBitCount = (USHORT) alBitmapFormats[1] ;
  220.  
  221.           hbm = GpiCreateBitmap (hpsMemory, &bmp, 0L, NULL, NULL) ;
  222.  
  223.                                    // Copy from screen to bitmap
  224.  
  225.           GpiSetBitmap (hpsMemory, hbm) ;
  226.  
  227.           aptl[0].x = 0 ;
  228.           aptl[0].y = 0 ;
  229.           aptl[1].x = cxPointer ;
  230.           aptl[1].y = cyPointer ;
  231.           aptl[2].x = ptlPointer.x - ptri.xHotspot ;
  232.           aptl[2].y = ptlPointer.y - ptri.yHotspot ;
  233.  
  234.           GpiBitBlt (hpsMemory, hpsScreen, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  235.  
  236.                                    // Draw pointer on screen
  237.  
  238.           WinDrawPointer (hpsScreen, (SHORT) aptl[2].x, (SHORT) aptl[2].y,
  239.                           hptr, DP_NORMAL) ;
  240.           }
  241.      else
  242.           {
  243.                                    // Copy from bitmap to screen
  244.  
  245.           aptl[0].x = ptlPointer.x - ptri.xHotspot ;
  246.           aptl[0].y = ptlPointer.y - ptri.yHotspot ;
  247.           aptl[1].x = aptl[0].x + cxPointer ;
  248.           aptl[1].y = aptl[0].y + cyPointer ;
  249.           aptl[2].x = 0 ;
  250.           aptl[2].y = 0 ;
  251.  
  252.           GpiBitBlt (hpsScreen, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  253.  
  254.                                    // Clean up
  255.  
  256.           GpiSetBitmap (hpsMemory, NULL) ;
  257.           GpiDestroyPS (hpsMemory) ;
  258.           DevCloseDC (hdcMemory) ;
  259.           GpiDeleteBitmap (hbm) ;
  260.           }
  261.      }
  262.  
  263. HBITMAP ScreenToBitmap (SHORT cxScreen, SHORT cyScreen, BOOL fIncludePtr,
  264.                                                         BOOL fMonochrome)
  265.      {
  266.      BITMAPINFOHEADER bmp ;
  267.      HBITMAP          hbm ;
  268.      HDC              hdcMemory ;
  269.      HPS              hpsScreen, hpsMemory ;
  270.      LONG             alBitmapFormats [2] ;
  271.      POINTL           aptl[3] ;
  272.      SIZEL            sizl ;
  273.  
  274.                                    // Create memory DC and PS
  275.  
  276.      hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  277.  
  278.      sizl.cx = sizl.cy = 0 ;
  279.      hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl,
  280.                               PU_PELS    | GPIF_DEFAULT |
  281.                               GPIT_MICRO | GPIA_ASSOC) ;
  282.  
  283.                                    // Create bitmap for destination
  284.  
  285.  
  286.      bmp.cbFix     = sizeof bmp ;
  287.      bmp.cx        = cxScreen ;
  288.      bmp.cy        = cyScreen ;
  289.  
  290.      if (fMonochrome)
  291.           {
  292.           bmp.cPlanes   = 1 ;
  293.           bmp.cBitCount = 1 ;
  294.           }
  295.      else
  296.           {
  297.           GpiQueryDeviceBitmapFormats (hpsMemory, 2L, alBitmapFormats) ;
  298.  
  299.           bmp.cPlanes   = (USHORT) alBitmapFormats[0] ;
  300.           bmp.cBitCount = (USHORT) alBitmapFormats[1] ;
  301.           }
  302.  
  303.      hbm = GpiCreateBitmap (hpsMemory, &bmp, 0L, NULL, NULL) ;
  304.  
  305.                                    // Copy from screen to bitmap
  306.  
  307.      if (hbm != NULL)
  308.           {
  309.           GpiSetBitmap (hpsMemory, hbm) ;
  310.           hpsScreen = WinGetScreenPS (HWND_DESKTOP) ;
  311.  
  312.           aptl[0].x = 0 ;
  313.           aptl[0].y = 0 ;
  314.           aptl[1].x = cxScreen ;
  315.           aptl[1].y = cyScreen ;
  316.           aptl[2].x = 0 ;
  317.           aptl[2].y = 0 ;
  318.  
  319.           if (fIncludePtr)
  320.                CopyPointerToScreen (hpsScreen, alBitmapFormats, TRUE) ;
  321.  
  322.           WinLockVisRegions (HWND_DESKTOP, TRUE) ;
  323.  
  324.           GpiBitBlt (hpsMemory, hpsScreen, 3L, aptl,
  325.                      fMonochrome ? ROP_NOTSRCCOPY : ROP_SRCCOPY, BBO_IGNORE) ;
  326.  
  327.           WinLockVisRegions (HWND_DESKTOP, FALSE) ;
  328.  
  329.           if (fIncludePtr)
  330.                CopyPointerToScreen (hpsScreen, alBitmapFormats, FALSE) ;
  331.  
  332.           WinReleasePS (hpsScreen) ;
  333.           GpiDestroyPS (hpsMemory) ;
  334.           DevCloseDC (hdcMemory) ;
  335.           }
  336.  
  337.      return hbm ;
  338.      }
  339.  
  340. BOOL IsBitmapMonoEGA (HBITMAP hbm)
  341.      {
  342.      BITMAPINFOHEADER bmp ;
  343.  
  344.      if (hbm != NULL)
  345.           {
  346.           GpiQueryBitmapParameters (hbm, &bmp) ;
  347.  
  348.           if (bmp.cx        == 640 &&
  349.               bmp.cy        == 350 &&
  350.               bmp.cPlanes   == 1   &&
  351.               bmp.cBitCount == 1)
  352.  
  353.                return TRUE ;
  354.           }
  355.      return FALSE ;
  356.      }
  357.  
  358. SHORT SaveBitmap (HBITMAP hbm, CHAR *szFilename)
  359.      {
  360.      BITMAPFILEHEADER bfh ;
  361.      BITMAPINFO       *pbmi ;
  362.      BYTE             *pbScan ;
  363.      FILE             *file ;
  364.      HDC              hdcMemory ;
  365.      HPS              hpsMemory ;
  366.      LONG             lBmpDataSize ;
  367.      SHORT            sRgbTableSize, sScanLineSize, sScan ;
  368.      SIZEL            sizl ;
  369.  
  370.                               // Get bitmap information
  371.  
  372.      bfh.bmp.cbFix = sizeof (BITMAPINFOHEADER) ;
  373.      GpiQueryBitmapParameters (hbm, &bfh.bmp) ;
  374.  
  375.      if (bfh.bmp.cPlanes != 1)
  376.           return IDS_MULTIPLANE ;
  377.  
  378.      sRgbTableSize = (1 << bfh.bmp.cPlanes * bfh.bmp.cBitCount) * sizeof (RGB);
  379.      sScanLineSize = ((bfh.bmp.cBitCount * bfh.bmp.cx + 31) / 32) * 4 *
  380.                        bfh.bmp.cPlanes ;
  381.      lBmpDataSize  = (LONG) sScanLineSize * bfh.bmp.cy ;
  382.  
  383.                               // Open file
  384.  
  385.      if (NULL == (file = fopen (szFilename, "wb")))
  386.           return IDS_FILEOPEN ;
  387.  
  388.                               // Set up file header and write it to file
  389.  
  390.      bfh.usType   = BFT_BMAP ;
  391.      bfh.cbSize   = sizeof (BITMAPFILEHEADER) + sRgbTableSize + lBmpDataSize ;
  392.      bfh.xHotspot = 0 ;
  393.      bfh.yHotspot = 0 ;
  394.      bfh.offBits  = sizeof (BITMAPFILEHEADER) + sRgbTableSize ;
  395.  
  396.      fwrite (&bfh, sizeof bfh, 1, file) ;
  397.  
  398.                               // Create memory DC and PS, and set bitmap in it
  399.  
  400.      hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  401.  
  402.      sizl.cx = sizl.cy = 0 ;
  403.      hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl, PU_PELS | GPIF_DEFAULT |
  404.                                                      GPIT_MICRO | GPIA_ASSOC) ;
  405.  
  406.      GpiSetBitmap (hpsMemory, hbm) ;
  407.  
  408.                               // Allocate memory for BITMAPINFO table & scans
  409.  
  410.      pbmi = malloc (sizeof (BITMAPINFOHEADER) + sRgbTableSize) ;
  411.  
  412.      pbmi->cbFix     = sizeof (BITMAPINFOHEADER) ;
  413.      pbmi->cPlanes   = bfh.bmp.cPlanes ;
  414.      pbmi->cBitCount = bfh.bmp.cBitCount ;
  415.  
  416.      pbScan = malloc (sScanLineSize) ;
  417.  
  418.                               // Loop through scan lines
  419.  
  420.      for (sScan = 0 ; sScan < bfh.bmp.cy ; sScan++)
  421.           {
  422.           GpiQueryBitmapBits (hpsMemory, (LONG) sScan, 1L, pbScan, pbmi) ;
  423.  
  424.           if (sScan == 0)
  425.                fwrite (&pbmi->argbColor[0], sRgbTableSize, 1, file) ;
  426.  
  427.           if (fwrite (pbScan, sScanLineSize, 1, file) == 0)
  428.                break ;
  429.           }
  430.                               // Cleanup after completion
  431.  
  432.      fclose (file) ;
  433.      free (pbmi) ;
  434.      free (pbScan) ;
  435.      GpiDestroyPS (hpsMemory) ;
  436.      DevCloseDC (hdcMemory) ;
  437.  
  438.      if (sScan != bfh.bmp.cy)
  439.           {
  440.           unlink (szFilename) ;
  441.           return IDS_DISKFULL ;
  442.           }
  443.  
  444.      return 0 ;
  445.      }
  446.  
  447. typedef struct
  448.      {
  449.      SHORT key1 ;
  450.      SHORT key2 ;
  451.      SHORT dxFile ;
  452.      SHORT dyFile ;
  453.      SHORT ScrAspectX ;
  454.      SHORT ScrAspectY ;
  455.      SHORT PrnAspectX ;
  456.      SHORT PrnAspectY ;
  457.      SHORT dxPrinter ;
  458.      SHORT dyPrinter ;
  459.      SHORT AspCorX ;
  460.      SHORT AspCorY ;
  461.      SHORT wCheck ;
  462.      SHORT res1 ;
  463.      SHORT res2 ;
  464.      SHORT res3 ;
  465.      SHORT bitmap[350][40] ;
  466.      }
  467.      PAINT ;
  468.  
  469. SHORT SavePaintFormat (HBITMAP hbm, CHAR *szFilename)
  470.      {
  471.      BITMAPINFO *pbmi ;
  472.      FILE       *file ;
  473.      HDC        hdcMemory ;
  474.      HPS        hpsMemory ;
  475.      PAINT      *ppaint ;
  476.      SHORT      i, j, sHold, sWrite ;
  477.      SIZEL      sizl ;
  478.                               // Allocate memory and open file
  479.  
  480.      if (!IsBitmapMonoEGA (hbm))
  481.           return IDS_MONOEGA ;
  482.  
  483.      if (NULL == (ppaint = malloc (sizeof (PAINT))))
  484.           return IDS_MEMORY ;
  485.  
  486.      if (NULL == (file = fopen (szFilename, "wb")))
  487.           {
  488.           free (ppaint) ;
  489.           return IDS_FILEOPEN ;
  490.           }
  491.                               // Set up Paint header for EGA
  492.  
  493.      ppaint->key1       = 0x6144 ;
  494.      ppaint->key2       = 0x4D6E ;
  495.      ppaint->dxFile     = 0x0280 ;
  496.      ppaint->dyFile     = 0x015E ;
  497.      ppaint->ScrAspectX = 0x0026 ;
  498.      ppaint->ScrAspectY = 0x0030 ;
  499.      ppaint->PrnAspectX = 0x0026 ;
  500.      ppaint->PrnAspectY = 0x0030 ;
  501.      ppaint->dxPrinter  = 0x0280 ;
  502.      ppaint->dyPrinter  = 0x015E ;
  503.      ppaint->AspCorX    = 0x0000 ;
  504.      ppaint->AspCorY    = 0x0000 ;
  505.      ppaint->wCheck     = 0x2C2A ;
  506.      ppaint->res1       = 0xB80E ;
  507.      ppaint->res2       = 0x0050 ;
  508.      ppaint->res3       = 0x8D50 ;
  509.  
  510.                               // Create memory DC and PS, and set bitmap in it
  511.  
  512.      hdcMemory = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  513.  
  514.      sizl.cx = sizl.cy = 0 ;
  515.      hpsMemory = GpiCreatePS (hab, hdcMemory, &sizl, PU_PELS | GPIF_DEFAULT |
  516.                                                      GPIT_MICRO | GPIA_ASSOC) ;
  517.  
  518.      GpiSetBitmap (hpsMemory, hbm) ;
  519.  
  520.                               // Allocate memory for bitmap header info
  521.  
  522.      pbmi = malloc (sizeof (BITMAPINFO) + sizeof (RGB)) ;
  523.  
  524.      pbmi->cbFix     = sizeof (BITMAPINFOHEADER) ;
  525.      pbmi->cx        = 640 ;
  526.      pbmi->cy        = 350 ;
  527.      pbmi->cPlanes   = 1 ;
  528.      pbmi->cBitCount = 1 ;
  529.                               // Get bitmap bits
  530.  
  531.      GpiQueryBitmapBits (hpsMemory, 0L, 350L, (PBYTE) ppaint->bitmap, pbmi) ;
  532.  
  533.      free (pbmi) ;
  534.                               // Convert to paint format and write
  535.  
  536.      for (i = 0 ; i < 350 / 2 ; i++)
  537.           for (j = 0 ; j < 40 ; j++)
  538.                {
  539.                sHold = ~ppaint->bitmap[i][j] ;
  540.                ppaint->bitmap[i][j] = ~ppaint->bitmap[350-i-1][j] ;
  541.                ppaint->bitmap[350-i-1][j] = sHold ;
  542.                }
  543.  
  544.      sWrite = fwrite (ppaint, sizeof (PAINT), 1, file) ;
  545.  
  546.                               // Clean up after completion
  547.      fclose (file) ;
  548.      free (ppaint) ;
  549.      GpiDestroyPS (hpsMemory) ;
  550.      DevCloseDC (hdcMemory) ;
  551.  
  552.      if (sWrite == 0)
  553.           {
  554.           unlink (szFilename) ;
  555.           return IDS_DISKFULL ;
  556.           }
  557.      return 0 ;
  558.      }
  559.